package info.motteke.qjdbc.db;

import static info.motteke.util.Closer.*;
import info.motteke.qjdbc.exception.QuickJDBCException;
import info.motteke.qjdbc.exception.SqlException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Hashtable;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public final class DataSourceConnectionFactory extends ConnectionFactory {

    private final DataSource ds;

    public DataSourceConnectionFactory(String name){
        this(name, null, null, null);
    }

    public DataSourceConnectionFactory(String name, Hashtable<?, ?> environment){
        this(name, null, null, environment);
    }

    public DataSourceConnectionFactory(String name, String user, String password){
        this(name, user, password, null);
    }

    public DataSourceConnectionFactory(String name, String user, String password, Hashtable<?, ?> environment){
        super(user, password);
        if(name == null){
            throw new IllegalArgumentException();
        }
        InitialContext c = null;
        try {
            c = getInitialContext(environment);
            ds = (DataSource)c.lookup(name);
            c.close();
        } catch (NamingException e) {
            throw new QuickJDBCException(e);
        } catch (ClassCastException e) {
            throw new QuickJDBCException(e);
        } finally {
            close(c);
        }
    }

    @Override
    protected Connection getConnection(){
        try {
            return ds.getConnection();
        } catch (SQLException e) {
            throw new SqlException(e);
        }
    }

    @Override
    protected Connection getConnection(String user, String password){
        try {
            return ds.getConnection(user, password);
        } catch (SQLException e) {
            throw new SqlException(e);
        }
    }

    private InitialContext getInitialContext(Hashtable<?, ?> environment) throws NamingException {
        if(environment == null){
            return new InitialContext();
        }else{
            return new InitialContext(environment);
        }
    }
}
